/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package graph.data.view;

import graph.data.Tree;
import graph.data.TreeNode;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.List;

/**
 *
 * @author Илья
 */
public class TreePanel extends javax.swing.JPanel {

    /**
     * Creates new form GraphPanel
     */
    
    Tree g;
    TreeVis gVis;
    TreeNodeVis vis_that_we_move_when_mouse_clicked = null;
    TreeNodeVis created;
    
    public TreePanel(Tree g) {
        this.g = g;
        initComponents();
        initUserComponents();
    }

    private TreeNode getNear(int x, int y)
    {
        for(TreeNode node : g.getNodes()) {
            TreeNodeVis nodeVis = gVis.getVisualisation(node);
            if (Point.distance(x, y, nodeVis.getX(), nodeVis.getY()) <= TreeNodeVis.POINT_RADIUS) {
                return node;
            }
        }
        return null;
    }
    
    private void initUserComponents() {
        gVis = new TreeVis(g);
        gVis.getVisualisation(g.getHead()).setX(100);
        gVis.getVisualisation(g.getHead()).setY(100);
        
        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent me) {
                if (me.getButton()==MouseEvent.BUTTON1){
                    TreeNode near = getNear(me.getX(), me.getY());
                    vis_that_we_move_when_mouse_clicked = gVis.getVisualisation(near);
                } else if (me.getButton() == MouseEvent.BUTTON3) {
                    TreeNode newNode = new TreeNode();
                    TreeNode oldNode = getNear(me.getX(), me.getY());
                    if (oldNode == null)
                        return;
                    
                    oldNode.getChildren().add(newNode);
                    g.AddNode(newNode);
                    gVis.refreshNodes();
                    created = gVis.getVisualisation(newNode);
		    created.setX(me.getX());
		    created.setY(me.getY());
                } else if (me.getButton() == MouseEvent.BUTTON2) {
                    TreeNode near = getNear(me.getX(), me.getY());
                    if (near == null)
                        return;
                    g.RemoveNode(near);
                    gVis.refreshNodes();
		    repaint();
                }
            }

            @Override
            public void mouseReleased(MouseEvent me) {
                vis_that_we_move_when_mouse_clicked = null;
                created = null;
            }
    
        });
	
        this.addMouseMotionListener(new MouseMotionAdapter() {

            @Override
            public void mouseDragged(MouseEvent me) {
               if (vis_that_we_move_when_mouse_clicked!=null){
                   vis_that_we_move_when_mouse_clicked.setX(me.getX());
                    vis_that_we_move_when_mouse_clicked.setY(me.getY());
                    repaint();
               }
               if (created!=null){
                    created.setX(me.getX());
                     created.setY(me.getY());
                     repaint();
               }
           }
        });
        
	addMouseWheelListener(new MouseWheelListener() {

	    @Override
	    public void mouseWheelMoved(MouseWheelEvent mwe) {
		TreeNode near = getNear(mwe.getX(), mwe.getY());
		if (near == null)
		    return;
		near.setValue(near.getValue() - mwe.getWheelRotation());
		repaint();
	    }
	});
    }

    @Override
    public void paint(Graphics grphcs) {
        super.paint(grphcs);
        gVis.GraphPaint(grphcs);
    }
    
    public void mark(List<TreeNode> nodes, Color color) {
	for(TreeNode node : nodes) {
	    TreeNodeVis vis = gVis.getVisualisation(node);
	    if (vis == null)
		continue;
	    vis.setColor(color);
	}
	repaint();
    }
    
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}
